package com.example.badyloans.servlet;

import com.example.badyloans.common.ReturnResult;
import com.example.badyloans.config.CalculationLiXIJIS;
import com.example.badyloans.dao.*;
import com.example.badyloans.pojo.*;
import javafx.scene.layout.BorderRepeat;
import org.apache.tomcat.jni.Local;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import com.example.badyloans.pojo.TBid;
import com.example.badyloans.dao.TBidMapper;
import com.example.badyloans.servlet.TBidService;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Collection;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;

@Service
public class TBidServiceImpl implements TBidService{
    @Resource
    private TBidMapper tBidMapper;
    @Resource
    private TBorrowService tBorrowService;
    @Resource
    private TBorrowMapper tBorrowMapper;
    @Resource
    private TUserWalletMapper tUserWalletMapper;
    @Resource
    private TAccountFlowMapper tAccountFlowMapper;
    @Resource
    private TRepaymentMapper tRepaymentMapper;
    @Resource
    private TRepaymentDetailMapper tRepaymentDetailMapper;

    @Override
    public int deleteByPrimaryKey(String id) {
        return tBidMapper.deleteByPrimaryKey(id);
    }

    @Override
    public int insertSelective(TBid record) {
        return tBidMapper.insertSelective(record);
    }

    @Override
    public TBid selectByPrimaryKey(String id) {
        return tBidMapper.selectByPrimaryKey(id);
    }

    @Override
    public TBid selectByPrimary1(String borrowid) {
        return tBidMapper.selectByPrimary1(borrowid);
    }

    @Override
    public List<TBid> selectByPrimary3(String borrowstate) {
        return tBidMapper.selectByPrimary3(borrowstate);
    }

    @Override
    public List<TBid> selectByPrimary2(String borrowid) {
        return tBidMapper.selectByPrimary2(borrowid);
    }

    @Override
    public int count() {
        return tBidMapper.count();
    }

    @Override
    public List<TBid> selectBYPrimaryKey1(String borrowid, Integer currentPageNo,
                                          Integer pageSize) {
        return tBidMapper.selectByPrimaryKey1(borrowid,currentPageNo,pageSize);
    }

    @Override
    public int updateByPrimaryKeySelective(TBid record) {
        return tBidMapper.updateByPrimaryKeySelective(record);
    }

    /**
     * 投标方法
     * @param bid
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public ReturnResult addBid(TBid bid) {
        //查询出账户的可用余额
        TUserWallet tUserWallet=tUserWalletMapper.selectByPrimaryKey(bid.getBidUserId());
        //查询出当前投标的记录表
        TBorrow tBorrow=tBorrowService.selectByPrimaryKey(bid.getBorrowId());
        //判断是否为招标中
        if (!(tBorrow.getBorrowState().equals(20))) {
            return ReturnResult.fail("不是招标中");
        }
        //判断当前时间是否超过招标截至时间   如果大于0   前面的比后面的大  小于0  后面的比前面的大
        if(tBorrow.getBidDeadline().compareTo(LocalDateTime.now())<0){
            //修改为流标
            tBorrow.setBorrowState(21);
            tBorrowService.updateByPrimaryKeySelective(tBorrow);
            //恢复借款人的可用授信额度和剩余授信额度
            tUserWallet.setCreditLine(tUserWallet.getCreditLine()+tBorrow.getBorrowAmount());
            tUserWallet.setResidualCreditLine(tUserWallet.getResidualCreditLine()+tBorrow.getBorrowAmount());
            int count=tUserWalletMapper.updateByPrimaryKeySelective(tUserWallet);
            return ReturnResult.fail("系统时间大于招标时间");
        }
        //如果投标金额大于可用余额就提示账户余额不足
        if(tUserWallet.getAvailableAmount()<bid.getBidAmount()){
            return ReturnResult.fail("账户余额不足");
        }
        //判断是否为同一人
        if (bid.getBidUserId().equals(tBorrow.getBorrowUserId())){
            return ReturnResult.fail("招标人和投标人不能是同一个人");
        }
        //最小投资为50元，并且投资金额必须为50的倍数
        //投标金额必须大于50，并且是50的倍数
        if(bid.getBidAmount()<5000||bid.getBidAmount()%50!=0){
            return ReturnResult.fail("投标金额不能小于50或不是50的倍数");
        }
        //判断投标金额是否大于总借款金额
        //如果你投资金额大于借款金额
        if(bid.getBidAmount()>tBorrow.getBorrowAmount()){
            return ReturnResult.fail("操作失败");
        }
        Integer updateone=0;
        Integer inserttwo=0;
        //判断是否是同一个人进行投标
        TBid bidByUserId=tBidMapper.selectone(bid.getBorrowId(),bid.getBidUserId());
        //投标利息
        Long lixi= CalculationLiXIJIS.calculationtotal(bid.getBidAmount(),tBorrow.getYearRate(),tBorrow.getRepaymentMonth(),tBorrow.getRepaymentType());
        //判断是否为空，为空则是第一次投标，
        if (bidByUserId==null){
            bid.setId(UUID.randomUUID().toString().replace("-","").toLowerCase());
            bid.setBidTime(LocalDateTime.now());
            bid.setBorrowTitle(tBorrow.getTitle());
            bid.setBorrowState(tBorrow.getBorrowState());
            bid.setYearRate(tBorrow.getYearRate());
            bid.setBidInterest(lixi);
            inserttwo = tBidMapper.insertSelective(bid);
        }else{
            // 不为空就是第二次或者第几次投标，进行叠加
            bidByUserId.setBidAmount(bidByUserId.getBidAmount()+bid.getBidAmount());
            bidByUserId.setBidInterest(bidByUserId.getBidInterest()+lixi);
            updateone=tBidMapper.updateByPrimaryKeySelective(bidByUserId);
        }
        //判断俩次是否大于0  都大于0就进行贷款标表的修改
        if(inserttwo>0||updateone>0){
            //判断投资金额加上已投资金额等于借款总金额的话，
            Long account=bid.getBidAmount()+tBorrow.getCurrentBidAmount();
            if(account.compareTo(tBorrow.getBorrowAmount())==0){
                tBorrow.setBorrowState(30);
            }
            //投标数量加1
            tBorrow.setBidNum(tBorrow.getBidNum()+1);
            //修改当前已投金额
            tBorrow.setCurrentBidAmount(tBorrow.getCurrentBidAmount()+bid.getBidAmount());
            //修改已投利息
            tBorrow.setCurrentBidInterest(tBorrow.getTotalInterest()+lixi);
            int update=tBorrowService.updateByPrimaryKeySelective(tBorrow);
            //修改用户资金账户表的可用金额    拿可用金额减去已投金额
            tUserWallet.setAvailableAmount(tUserWallet.getAvailableAmount()-bid.getBidAmount());
            tUserWallet.setFreezeAmount(tUserWallet.getFreezeAmount()+bid.getBidAmount());
            int update1=tUserWalletMapper.updateByPrimaryKeySelective(tUserWallet);
            if(update>0 && update1>0){
                return ReturnResult.succes();
            }else{
                return ReturnResult.fail("投资失败");
            }
        }else{
            return ReturnResult.fail("投资失败");
        }
    }


    @Override
    public TBid selectone(String borrowId, String bidUserId) {
        return tBidMapper.selectone(borrowId,bidUserId);
    }

    /**
     * 放款审核拒绝和通过
     * @param tBid
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean selecttwo(TBid tBid) {
        int updatetuserwallet=0;
        int inserttAccountFlow=0;
        //查出贷款表的记录
        TBorrow tBorrow=tBorrowMapper.selectByPrimaryKey(tBid.getBorrowId());
        //查询出投标记录表的记录
        List<TBid> tBid1=tBidMapper.selectByPrimary2(tBid.getBorrowId());

        TBid tBid3=tBidMapper.selectByPrimary1(tBid.getBorrowId());
        //查询投标人的资金账户
        TUserWallet tUserWallet=tUserWalletMapper.selectByPrimaryKey(tBid3.getBidUserId());
        //查询出借款人信息
        TUserWallet tUserWallet1=tUserWalletMapper.selectByPrimaryKey(tBorrow.getBorrowUserId());
        //如果为审核拒绝
        if(tBid.getBorrowState().equals(31)){
            //审核拒接
            //  1.1更新投标人的资金账户，退回投资金额,,恢复投标人的冻结金额
            for (int i=0;i<tBid1.size();i++){
                tUserWallet.setAvailableAmount(tUserWallet.getAvailableAmount()+tBid1.get(i).getBidAmount());
                tUserWallet.setFreezeAmount(tUserWallet.getFreezeAmount()-tBid1.get(i).getBidAmount());
                updatetuserwallet=tUserWalletMapper.updateByPrimaryKeySelective(tUserWallet);
                //  1.2  生成投标人的退款流水
                TAccountFlow tAccountFlow = new TAccountFlow();
                tAccountFlow.setAccountId(tUserWallet.getAccountId());
                tAccountFlow.setAmount(tBid1.get(i).getBidAmount());
                tAccountFlow.setFlowType(21);
                tAccountFlow.setAvailableAmount(tUserWallet.getAvailableAmount());
                tAccountFlow.setFreezeAmount(tUserWallet.getFreezeAmount());
                tAccountFlow.setRemark("审核拒绝，退回资金"+tBid1.get(i).getBidAmount()+"元");
                tAccountFlow.setCreateTime(LocalDateTime.now());
                inserttAccountFlow= tAccountFlowMapper.insertSelective(tAccountFlow);

                //  1.3  更新投标记录本身的状态
                TBid tBid2=new TBid();
                tBid2.setBorrowId(tBorrow.getId());
                tBid2.setBorrowState(31);
                int updatetbid=tBidMapper.updateByPrimaryKeySelective(tBid2);
                tBorrow.setBorrowState(31);
                int updatetborrow=tBorrowMapper.updateByPrimaryKeySelective(tBorrow);
            }
            //  1.4  恢复借款人的授信额度
            tUserWallet1.setCreditLine(tUserWallet1.getCreditLine()+tBorrow.getBorrowAmount());
            tUserWallet1.setResidualCreditLine(tUserWallet1.getResidualCreditLine()+tBorrow.getBorrowAmount());
            int updateUserwallet=tUserWalletMapper.updateByPrimaryKeySelective(tUserWallet1);
            if(updateUserwallet>0){
                return  true;
            }else{
                return false;
            }
        }else{//审核通过
            // 2.1 将借款总金额转移到借款人的资金账户
            tUserWallet1.setAvailableAmount(tUserWallet1.getAvailableAmount()+tBorrow.getBorrowAmount());
            // 2.2  计算出借款人的代还总金额和代还利息
            tUserWallet1.setRepaidAmount(CalculationLiXIJIS.calcuationTotalAmountAndInterset(tBorrow.getBorrowAmount(),tBorrow.getRepaymentMonth()
                                    ,tBorrow.getYearRate(),tBorrow.getRepaymentType()).longValue());
            int update=tUserWalletMapper.updateByPrimaryKeySelective(tUserWallet1);
            // 2.3 生成收款流水
            TAccountFlow tAccountFlow = new TAccountFlow();
            tAccountFlow.setAccountId(tBorrow.getBorrowUserId());
            tAccountFlow.setAmount(tBorrow.getBorrowAmount());
            tAccountFlow.setFlowType(10);//借款成功
            tAccountFlow.setAvailableAmount(tUserWallet.getAvailableAmount());
            tAccountFlow.setFreezeAmount(tUserWallet.getFreezeAmount());
            tAccountFlow.setRemark("借款成功，贷款金额为"+tBorrow.getBorrowAmount()+"元");
            tAccountFlow.setCreateTime(LocalDateTime.now());
            int insert=tAccountFlowMapper.insertSelective(tAccountFlow);

            // 2.4  为每一位投资人生成一条投资流水
            List<TBid> tBidList=tBidMapper.selectByPrimary2(tBid.getBorrowId());
            for (int i=0;i<tBidList.size();i++){
                TAccountFlow tAccountFlow1 = new TAccountFlow();
                tAccountFlow1.setAccountId(tBidList.get(i).getBidUserId());
                tAccountFlow1.setAmount(tBidList.get(i).getBidAmount());
                tAccountFlow1.setFlowType(22);
                tAccountFlow1.setAvailableAmount(tUserWallet.getAvailableAmount());
                tAccountFlow1.setFreezeAmount(tUserWallet.getFreezeAmount());
                tAccountFlow1.setRemark("投资成功，投资金额为："+tBidList.get(i).getBidAmount());
                tAccountFlow1.setCreateTime(LocalDateTime.now());
                int insert1=tAccountFlowMapper.insertSelective(tAccountFlow1);
            }
            // 2.5 根据还款周期，生成还款计划
            TRepayment tRepayment = new TRepayment();
            Long getBorrowAmount1=tBorrow.getBorrowAmount();
            System.out.println(getBorrowAmount1);
            for (int i=0;i<tBorrow.getRepaymentMonth();i++){
                tRepayment.setBorrowType(tBorrow.getBorrowType());
                tRepayment.setBorrowTitle(tBorrow.getTitle());
                tRepayment.setBorrowId(tBorrow.getId());
                tRepayment.setBorrowUserId(tBorrow.getBorrowUserId());
                tRepayment.setCreateTime(LocalDateTime.now());
                //计算还款截至日期
                tRepayment.setDeadline(LocalDateTime.now().plusMonths(i+1));
                tRepayment.setId(UUID.randomUUID().toString().replace("-",""));
                //计算本期还款总利息
                tRepayment.setInterest(CalculationLiXIJIS.calculationInterestPerMonth(tBorrow.getYearRate(),tBorrow.getRepaymentType()
                        ,getBorrowAmount1,tBorrow.getRepaymentMonth()));
                //本期还款本金
                tRepayment.setPrincipal(CalculationLiXIJIS.calculationPrincipalPerMonth(tBorrow.getYearRate(),tBorrow.getRepaymentType()
                        ,getBorrowAmount1,tBorrow.getRepaymentMonth()));
                //本期还款总金额
                tRepayment.setTotalAmount(tRepayment.getPrincipal()+tRepayment.getInterest());

                getBorrowAmount1=tBorrow.getBorrowAmount()-tRepayment.getPrincipal();
                //还款期数
                tRepayment.setPeriod(i+1);
                //还款状态
                tRepayment.setState(2);
                //借款类型
                tRepayment.setRepaymentType(tBorrow.getBorrowType());
                //还款日期
                tRepayment.setRepaymentTime(LocalDateTime.now());

                tRepaymentMapper.insertSelective(tRepayment);
            }
            // 2.6 根据投标记录表，为每位投标记录人生成还款计划明细，包含每月应收的本金和利息
            List<TBid> tBidList1=tBidMapper.selectByPrimary2(tBid.getBorrowId());
            for(int i=0;i<tBidList1.size();i++){
                Long getBorrowAmount2=tBidList1.get(i).getBidAmount();
                TRepaymentDetail tRepaymentDetail=new TRepaymentDetail();
                tRepaymentDetail.setBorrowId(tBorrow.getBorrowUserId());
                tRepaymentDetail.setId(UUID.randomUUID().toString().replace("-",""));
                tRepaymentDetail.setBidId(tBid.getBorrowId());
                tRepaymentDetail.setBidUserId(tBorrow.getBorrowUserId());
                tRepaymentDetail.setRepaymentId(tRepayment.getId());
                tRepaymentDetail.setBorrowUserId(tBorrow.getBorrowUserId());
                tRepaymentDetail.setBidUserId(tBid3.getBidUserId());
                tRepaymentDetail.setBorrowTitle(tBorrow.getTitle());
                //还款本金
                tRepaymentDetail.setPrincipal(CalculationLiXIJIS.calculationPrincipalPerMonth(tBorrow.getYearRate(),tBorrow.getRepaymentType()
                        ,getBorrowAmount2,tBorrow.getRepaymentMonth()));
                //还款
                tRepaymentDetail.setInterest(CalculationLiXIJIS.calculationInterestPerMonth(tBorrow.getYearRate(),tBorrow.getRepaymentType()
                        ,getBorrowAmount2,tBorrow.getRepaymentMonth()));
                getBorrowAmount2=tBorrow.getBorrowAmount()-tRepayment.getPrincipal();
                //总金额+总利息
                tRepaymentDetail.setTotalAmount(tRepaymentDetail.getPrincipal()+tRepaymentDetail.getInterest());
                tRepaymentDetail.setPeriod(i+1);
                tRepaymentDetail.setDeadline(LocalDateTime.now().plusDays(i+1));
                tRepaymentDetail.setRepaymentTime(LocalDateTime.now());
                tRepaymentDetail.setRepaymentType(tBorrow.getRepaymentType());
                tRepaymentDetail.setCreateTime(LocalDateTime.now());
                int insert2=tRepaymentDetailMapper.insertSelective(tRepaymentDetail);
            }
            // 2.7 跟新标的状态为还款中
            //  1.3  更新投标记录本身的状态
            TBid tBid2=new TBid();
            tBid2.setBorrowId(tBorrow.getId());
            tBid2.setBorrowState(40);
            int updatetbid=tBidMapper.updateByPrimaryKeySelective(tBid2);
            tBorrow.setBorrowState(40);
            int updatetborrow=tBorrowMapper.updateByPrimaryKeySelective(tBorrow);
            return updatetbid>0 && updatetborrow>0;
        }
    }
}
